home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archivers / XpkDisk / prefsmain.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  13KB  |  655 lines

  1. /*-
  2.  * PREFSMAIN.C
  3.  *
  4.  * The main file of the xpkdisk preferences utility.
  5.  *
  6.  * $Id: prefsmain.c,v 1.5 1995/04/08 20:23:48 Rhialto Exp $
  7.  * $Log: prefsmain.c,v $
  8.  * Revision 1.5  1995/04/08  20:23:48  Rhialto
  9.  * Add/correct version strings.
  10.  *
  11.  * Revision 1.4  1995/04/02  14:58:51  Rhialto
  12.  * Change #ifdef into #if.
  13.  * Update for DICE 3.0. Lots more casts.
  14.  *
  15.  * Revision 1.3  1993/11/08  13:11:15  Rhialto
  16.  * Add RCS tags.
  17.  *
  18.  *
  19.  * This code is (C) Copyright 1992-1995 by Olaf Seibert. All rights reserved.
  20.  * May not be used or copied without a licence.
  21. -*/
  22.  
  23. #define INTUI_V36_NAMES_ONLY
  24.  
  25. #include "xpkdisk.h"
  26.  
  27. #ifndef LIBRARIES_GADTOOLS_H
  28. #include <libraries/gadtools.h>
  29. #endif
  30. #ifndef LIBRARIES_ASL_H
  31. #include <libraries/asl.h>
  32. #endif
  33. #ifndef INTUITION_GADGETCLASS_H
  34. #include <intuition/gadgetclass.h>
  35. #endif
  36. #ifndef DOS_DOS_H
  37. #include <dos/dos.h>
  38. #endif
  39. #ifndef DOS_DOSEXTENS_H
  40. #include <dos/dosextens.h>
  41. #endif
  42. #ifndef DOS_FILEHANDLER_H
  43. #include <dos/filehandler.h>
  44. #endif
  45. #ifndef EXEC_MEMORY_H
  46. #include <exec/memory.h>
  47. #endif
  48.  
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <stdarg.h>
  53.  
  54. #include <clib/exec_protos.h>
  55. #include <clib/intuition_protos.h>
  56. #include <clib/gadtools_protos.h>
  57. #include <clib/asl_protos.h>
  58. #include <clib/alib_protos.h>
  59. #include <clib/dos_protos.h>
  60.  
  61. #include "prefswindow.h"
  62.  
  63. static const char rcsId[] = "$Id: prefsmain.c,v 1.5 1995/04/08 20:23:48 Rhialto Exp $";
  64.  
  65. struct Library *GadToolsBase;
  66. struct IntuitionBase *IntuitionBase;
  67. struct Library *AslBase;
  68. extern struct ExecBase *SysBase;
  69.  
  70. struct Settings {
  71.     short        MaxCache;
  72.     ushort        CacheFlags;
  73.     char        CacheCMDUPDATE;
  74.     char        CacheDELAY;
  75.     char        CacheSAFE;
  76.     char        Licensed;
  77.     short        CacheTimeout;
  78.     char        XPKPackMethod[10];     /* "XXXX.100" */
  79. };
  80.  
  81. const char    DevName[] = "xpkdisk.device";
  82. long        DevUnit;
  83. struct XpkDiskUnit *Unit;
  84. struct MsgPort *ReplyPort;
  85. struct IOExtTD *IOReq;
  86. struct FileRequest *FileRequest;
  87. struct Settings Defaults = {
  88.     MAX_CACHE,
  89.     CACHE_FLAGS,
  90.     (CACHE_FLAGS & CACHEF_CMDUPDATE) != 0,
  91.     (CACHE_FLAGS & CACHEF_DELAY) != 0,
  92.     (CACHE_FLAGS & CACHEF_SAFEWRITE) != 0,
  93.     1,
  94.     CACHE_TIMEOUT,
  95.     PACKING_METHOD
  96. };
  97. struct Settings Settings;
  98. struct Settings Initial;
  99.  
  100. const char    idString[] = "\0$VER: xdPrefs " STR(VERSION) "." STR(REVISION) "\r\n";
  101. const char    OkString[] = "Ok";
  102. const char    AbortString[] = "Abort";
  103. const char    PanicString[] = "Panic!";
  104. const char    Env[] = CONFIGFILE;
  105. const char    EnvArc[] = CONFIGFILE_ARC;
  106.  
  107. void        Show(void);
  108. void        Hide(void);
  109. void        SetGadgetAttr(int id, ULONG tag, ULONG value);
  110. int        Save(char *filename, int notify);
  111. void        SelectUnit(int unit);
  112. void        DeselectUnit(void);
  113. extern int    ReadConfig(UNIT *unit, char *buf, int sz);
  114.  
  115. #define DONE_DONE   1
  116.  
  117. void
  118. GT_SetGadgetAttrs(struct Gadget *gad, struct Window *win,
  119.           struct Requester *req, Tag tag1, ... )
  120. {
  121.     GT_SetGadgetAttrsA(gad, win, req, (void *)&tag1);
  122. }
  123.  
  124. APTR
  125. GetVisualInfo(struct Screen *screen, Tag tag1, ... )
  126. {
  127.     return GetVisualInfoA(screen, (void *)&tag1);
  128. }
  129.  
  130. void
  131. DrawBevelBox(struct RastPort *rport, long left, long top, long width,
  132.          long height, Tag tag1, ... )
  133. {
  134.     DrawBevelBoxA(rport, left, top, width, height, (void *)&tag1);
  135. }
  136.  
  137. struct Menu *
  138. CreateMenus(struct NewMenu *newmenu, Tag tag1, ... )
  139. {
  140.     return CreateMenusA(newmenu, (void *)&tag1);
  141. }
  142.  
  143. BOOL
  144. LayoutMenus(struct Menu *firstmenu, APTR vi, Tag tag1, ... )
  145. {
  146.     return LayoutMenusA(firstmenu, vi, (void *)&tag1);
  147. }
  148.  
  149. long min(long a, long b)
  150. {
  151.     return a < b? a : b;
  152. }
  153.  
  154. void
  155. Die(void)
  156. {
  157.     Hide();
  158.     DeselectUnit();
  159.  
  160.     if (IOReq) {
  161.     DeleteExtIO((struct IORequest *)IOReq);
  162.     IOReq = NULL;
  163.     }
  164.  
  165.     if (ReplyPort) {
  166.     DeletePort(ReplyPort);
  167.     ReplyPort = NULL;
  168.     }
  169.  
  170.     if (AslBase) {
  171.     if (FileRequest) {
  172.         FreeAslRequest(FileRequest);
  173.         FileRequest = NULL;
  174.     }
  175.  
  176.     CloseLibrary(AslBase);
  177.     AslBase = NULL;
  178.     }
  179.     if (IntuitionBase) {
  180.     CloseLibrary(IntuitionBase);
  181.     IntuitionBase = NULL;
  182.     }
  183.     if (GadToolsBase) {
  184.     CloseLibrary(GadToolsBase);
  185.     GadToolsBase = NULL;
  186.     }
  187.     exit(0);
  188. }
  189.  
  190. void
  191. OpenAll(int argc, char **argv)
  192. {
  193.     extern struct DosLibrary *DOSBase;
  194.  
  195.     if (DOSBase->dl_lib.lib_Version < 37) {
  196.     puts("Sorry, requires at least V37...");
  197.     Die();
  198.     }
  199.     GadToolsBase = OpenLibrary("gadtools.library", 37L);
  200.     if (!GadToolsBase)
  201.     Die();
  202.  
  203.     IntuitionBase = OpenLibrary("intuition.library", 37L);
  204.     if (!IntuitionBase)
  205.     Die();
  206.  
  207.     AslBase = OpenLibrary("asl.library", 37L);
  208.     if (!AslBase)
  209.     Die();
  210.  
  211.     ReplyPort = CreatePort(NULL, 0);
  212.     if (!ReplyPort)
  213.     Die();
  214.  
  215.     IOReq = (struct IOExtTD *)CreateExtIO(ReplyPort, sizeof(*IOReq));
  216.     if (!IOReq)
  217.     Die();
  218.  
  219.     Show();
  220. }
  221.  
  222. void
  223. Show(void)
  224. {
  225.     if (PrefsWnd) {
  226.     WindowToFront(PrefsWnd);
  227.     return;         /* already open */
  228.     }
  229.  
  230.     if (SetupScreen())
  231.     Die();
  232.  
  233.     if (OpenPrefsWindow())
  234.     Die();
  235.  
  236.     SelectUnit(DevUnit);
  237. }
  238.  
  239. void
  240. Hide(void)
  241. {
  242.     if (PrefsWnd) {
  243.     struct IntuiMessage *msg;
  244.  
  245.     while (msg = GT_GetIMsg(PrefsWnd->UserPort)) {
  246.         GT_ReplyIMsg(msg);
  247.     }
  248.     }
  249.  
  250.     ClosePrefsWindow();
  251.     CloseDownScreen();
  252. }
  253.  
  254. void
  255. SetGadgetAttr(int id, ULONG tag, ULONG value)
  256. {
  257.     GT_SetGadgetAttrs(PrefsGadgets[id], PrefsWnd, NULL,
  258.               tag, value,
  259.               TAG_END);
  260. }
  261.  
  262. int
  263. Confirm(char *fmt, char *buttons, ...)
  264. {
  265.     static struct EasyStruct er0 = {
  266.     sizeof er0, 0, "xpkdisk Prefs",
  267.     NULL,
  268.     NULL
  269.     };
  270.     struct EasyStruct er;
  271.     va_list        va;
  272.  
  273.     er = er0;
  274.     er.es_TextFormat = fmt;
  275.     er.es_GadgetFormat = buttons;
  276.     va_start(va, buttons);
  277.       return EasyRequestArgs(PrefsWnd, &er, NULL, va);
  278.     va_end(va)          /* produces error if it doesn't expand to empty */
  279. }
  280.  
  281. void
  282. DeselectUnit(void)
  283. {
  284.     if (IOReq->iotd_Req.io_Unit != NULL &&
  285.     IOReq->iotd_Req.io_Unit != (void *)-1)
  286.     CloseDevice((struct IORequest *)IOReq);
  287.  
  288.     IOReq->iotd_Req.io_Unit = NULL;
  289.     Unit = NULL;
  290. }
  291.  
  292. void
  293. UpdateGadgets(void)
  294. {
  295.     SetGadgetAttr(GDX_UNIT, GTSL_Level, DevUnit);
  296.     SetGadgetAttr(GDX_MAXCACHE, GTSL_Level, Settings.MaxCache);
  297.     SetGadgetAttr(GDX_CMDUPDATE, GTCB_Checked, Settings.CacheCMDUPDATE);
  298.     SetGadgetAttr(GDX_DELAY, GTCB_Checked, Settings.CacheDELAY);
  299.     SetGadgetAttr(GDX_SAFE, GTCB_Checked, Settings.CacheSAFE);
  300.     SetGadgetAttr(GDX_TIME, GTSL_Level, Settings.CacheTimeout);
  301.     SetGadgetAttr(GDX_METHOD, GTST_String, (ULONG)Settings.XPKPackMethod);
  302. }
  303.  
  304. void
  305. ConfigFromUnit(UNIT *unit)
  306. {
  307.     Settings.MaxCache = unit->xu_MaxCache;
  308.     Settings.CacheFlags = unit->xu_CacheFlags;
  309.     Settings.CacheCMDUPDATE = (Settings.CacheFlags & CACHEF_CMDUPDATE) != 0;
  310.     Settings.CacheDELAY     = (Settings.CacheFlags & CACHEF_DELAY) != 0;
  311.     Settings.CacheSAFE        = (Settings.CacheFlags & CACHEF_SAFEWRITE) != 0;
  312.     Settings.Licensed        = (Settings.CacheFlags & CACHEF_LICENSED) != 0;
  313.     Settings.CacheTimeout = unit->xu_CacheTimeout;
  314.     strcpy(Settings.XPKPackMethod, unit->xu_XPKPackMethod);
  315.  
  316.     UpdateGadgets();
  317. }
  318.  
  319. void
  320. SelectUnit(int unit)
  321. {
  322.     if (Unit && unit == DevUnit)
  323.     return;
  324.  
  325.     DeselectUnit();
  326.  
  327.     DevUnit = unit;
  328.     if (OpenDevice(DevName, unit, (struct IORequest *)IOReq, 0) != 0) {
  329.     DeselectUnit();
  330.     Confirm("Cannot open unit %ld", OkString, unit);
  331.     return;
  332.     }
  333.  
  334.     /* Make sure unit has initialised itself */
  335.     IOReq->iotd_Req.io_Command = CMD_UPDATE;
  336.     DoIO((struct IORequest *)IOReq);
  337.  
  338.     Unit = (struct XpkDiskUnit *)IOReq->iotd_Req.io_Unit;
  339.     ConfigFromUnit(Unit);
  340.     Initial = Settings;
  341. }
  342.  
  343. int
  344. Save(char *filename, int notify)
  345. {
  346.     char        buffer[160];
  347.     BPTR        fh;
  348.  
  349.     sprintf(buffer, filename, DevUnit);
  350.  
  351.     if (fh = Open(buffer, MODE_NEWFILE)) {
  352.     sprintf(buffer, S_CMDUPDATE "=%d,"
  353.             S_DELAY "=%d,"
  354.             S_SAFEWRITE "=%d,"
  355.             S_MaxCache "=%d,"
  356.             S_CacheTimeout "=%d,"
  357.             S_XPKPackMethod "=%s,"
  358.             S_LICENSED "=%d",
  359.         Settings.CacheCMDUPDATE,
  360.         Settings.CacheDELAY,
  361.         Settings.CacheSAFE,
  362.         Settings.MaxCache,
  363.         Settings.CacheTimeout,
  364.         Settings.XPKPackMethod,
  365.         Settings.Licensed);
  366.     Write(fh, buffer, strlen(buffer));
  367.     Close(fh);
  368.  
  369.     if (notify && Unit) {
  370.         IOReq->iotd_Req.io_Command = CMD_RESET;
  371.         DoIO((struct IORequest *)IOReq);
  372.     }
  373.     return 1;
  374.     }
  375.  
  376.     Confirm("Error writing \"%s\"", OkString, buffer);
  377.     return 0;
  378. }
  379.  
  380. void
  381. DoSaveAs(void)
  382. {
  383.     struct FileRequester *fr;
  384.  
  385.     if (FileRequest == NULL) {
  386.     FileRequest = (struct FileRequester *)
  387.               AllocAslRequest(ASL_FileRequest, NULL);
  388.     }
  389.  
  390.     if (fr = FileRequest) {
  391.     unsigned char    buffer[256];
  392.  
  393.     if (AslRequestTags(fr,
  394.                 ASL_Hail, "Save settings as",
  395.                 ASL_OKText, "Save",
  396.                 ASL_FuncFlags, FILF_SAVE,
  397.                 TAG_DONE
  398.               ) == 0) {
  399.         goto end;
  400.     }
  401.     strncpy(buffer, fr->rf_Dir, sizeof (buffer) - 1);
  402.     AddPart(buffer, fr->rf_File, sizeof (buffer) - 1);
  403.  
  404.     Save(buffer, 0);
  405.     end:
  406.     }
  407. }
  408.  
  409. void
  410. DoOpen(int ask)
  411. {
  412.     struct FileRequester *fr;
  413.     static        int Ask;
  414.  
  415.     if (FileRequest == NULL) {
  416.     FileRequest = (struct FileRequester *)
  417.               AllocAslRequest(ASL_FileRequest, NULL);
  418.     ask = 1;
  419.     }
  420.  
  421.     ask |= Ask;
  422.  
  423.     if (fr = FileRequest) {
  424.     unsigned char    buffer[256];
  425.     UNIT        unit;
  426.  
  427.     if (ask &&
  428.         AslRequestTags(fr,
  429.                 ASL_Hail, "Load settings",
  430.                 ASL_OKText, "Load",
  431.                 ASL_FuncFlags, 0,
  432.                 TAG_DONE
  433.               ) == 0) {
  434.         Ask = 1;
  435.         goto end;
  436.     }
  437.     strncpy(buffer, fr->rf_Dir, sizeof (buffer) - 1);
  438.     AddPart(buffer, fr->rf_File, sizeof (buffer) - 1);
  439.     Ask = 0;
  440.  
  441.     memset(&unit, 0, sizeof(unit));
  442.     /*
  443.      * I admit, this is roundabout, but saves duplicating the
  444.      * parsing function by using the same code as the device.
  445.      */
  446.     ReadConfig(&unit, buffer, sizeof(buffer));
  447.     ConfigFromUnit(&unit);
  448.     end: ;
  449.     }
  450. }
  451.  
  452. int
  453. DoAbout(void)
  454. {
  455.     struct EasyStruct er = {
  456.     sizeof er, 0, "About...",
  457. "xpkdisk.device \xA9 1995 by Olaf Seibert.\n"
  458. "\n"
  459. "  This program is distributed in the hope that it will be useful,\n"
  460. "  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  461. "  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
  462. "\n"
  463. "See documentation and GNU General Public License for distribution.",
  464.             "Accept License|Reject License"
  465.     };
  466.  
  467.     if (EasyRequestArgs(PrefsWnd, &er, NULL, NULL) == 0) {
  468.     return DONE_DONE;
  469.     }
  470.     Settings.Licensed = 1;
  471.     return 0;
  472. }
  473.  
  474. void
  475. MaybeAbout(void)
  476. {
  477.     if (!Settings.Licensed && DoAbout())
  478.     Die();
  479. }
  480.  
  481. int
  482. DoGadget(struct IntuiMessage *imsg)
  483. {
  484.     struct Gadget  *gd;
  485.     int         id;
  486.  
  487.     gd = (struct Gadget *) imsg->IAddress;
  488.     if (gd == NULL)
  489.     return 0;
  490.     id = gd->GadgetID;
  491.  
  492.     switch (id) {
  493.     case GD_UNIT:
  494.     SelectUnit(imsg->Code);
  495.     break;
  496.     case GD_MAXCACHE:
  497.     Settings.MaxCache = imsg->Code;
  498.     break;
  499.     case GD_CMDUPDATE:
  500.     Settings.CacheCMDUPDATE = (gd->Flags & GFLG_SELECTED) != 0;
  501.     break;
  502.     case GD_DELAY:
  503.     Settings.CacheDELAY = (gd->Flags & GFLG_SELECTED) != 0;
  504.     break;
  505.     case GD_SAFE:
  506.     Settings.CacheSAFE = (gd->Flags & GFLG_SELECTED) != 0;
  507.     break;
  508.     case GD_TIME:
  509.     Settings.CacheTimeout = imsg->Code;
  510.     break;
  511.     case GD_METHOD:
  512.     strncpy(Settings.XPKPackMethod, GetString(gd), 9);
  513.     break;
  514.     case GD_SAVE:
  515.     Save(EnvArc, FALSE);
  516.     /* fall through: SAVE implies USE. */
  517.     case GD_USE:
  518.     Save(Env, TRUE);
  519.     break;
  520.     case GD_QUIT:
  521.     return DONE_DONE;
  522.     }
  523.  
  524.     return 0;
  525. }
  526.  
  527. int
  528. DoMenu(struct IntuiMessage *imsg)
  529. {
  530.     int         menu = MENUNUM(imsg->Code);
  531.     int         item = ITEMNUM(imsg->Code);
  532.  
  533.     switch (menu) {
  534.     case 0:        /* Project */
  535.     switch (item) {
  536.     case 0:     /* - About... */
  537.         return DoAbout();
  538.     case 1:     /* - Open... */
  539.         DoOpen(1);
  540.         break;
  541.     case 2:     /* - Save */
  542.         Save(EnvArc, FALSE);
  543.         goto use;
  544.     case 3:     /* - Save As... */
  545.         DoSaveAs();
  546.         break;
  547.     case 4:     /* - Use */
  548.     use:
  549.         Save(Env, TRUE);
  550.         break;
  551.     case 6:     /* - Quit */
  552.         return DONE_DONE;
  553.     }
  554.     break;
  555.     case 1:        /* Edit */
  556.     switch (item) {
  557.     case 0:     /* - Reset to defaults */
  558.         Settings = Defaults;
  559.         UpdateGadgets();
  560.         break;
  561.     case 1:     /* - Last saved */
  562.         DoOpen(0);
  563.         break;
  564.     case 2:     /* - Restore */
  565.         Settings = Initial;
  566.         UpdateGadgets();
  567.         break;
  568.     }
  569.     break;
  570.     }
  571.     return 0;
  572. }
  573.  
  574. void
  575. MainLoop(void)
  576. {
  577.     long        waitmask;
  578.     long        mainmask;
  579.     long        mask;
  580.     int         done;
  581.  
  582.     done = 0;
  583.  
  584.     if (PrefsWnd)
  585.     mainmask = 1L << PrefsWnd->UserPort->mp_SigBit;
  586.     else
  587.     mainmask = 0;
  588.  
  589.     waitmask = mainmask | SIGBREAKF_CTRL_C;
  590.  
  591.     while (!done) {
  592.     mask = Wait(waitmask);
  593.     if (mask & SIGBREAKF_CTRL_C) {
  594.         done = DONE_DONE;
  595.         break;
  596.     }
  597.     if (mask & mainmask) {
  598.         struct IntuiMessage *imsg;
  599.  
  600.         while (imsg = GT_GetIMsg(PrefsWnd->UserPort)) {
  601.         switch (imsg->Class) {
  602.         case IDCMP_CLOSEWINDOW:
  603.             done = DONE_DONE;
  604.             break;
  605.         case IDCMP_GADGETDOWN:
  606.         case IDCMP_GADGETUP:
  607.         case IDCMP_MOUSEMOVE:
  608.             done = DoGadget(imsg);
  609.             break;
  610.         case IDCMP_MENUPICK:
  611.             done = DoMenu(imsg);
  612.             break;
  613.         case IDCMP_REFRESHWINDOW:
  614.             GT_BeginRefresh(imsg->IDCMPWindow);
  615.             PrefsRender();
  616.             GT_EndRefresh(imsg->IDCMPWindow, TRUE);
  617.             break;
  618.         }
  619.         GT_ReplyIMsg(imsg);
  620.         }
  621.     }
  622.     }
  623. }
  624.  
  625. void chkabort(void) {}      /* DICE specific. */
  626.  
  627. int
  628. main(int argc, char **argv)
  629. {
  630.     OpenAll(argc, argv);
  631.     MaybeAbout();
  632.     MainLoop();
  633.     Die();
  634.  
  635.     return 0;
  636. }
  637.  
  638. #ifndef WORKBENCH_STARTUP_H
  639. #include <workbench/startup.h>
  640. #endif
  641.  
  642. int
  643. wbmain(struct WBStartup *wbs)
  644. {
  645.     int         rc;
  646.     long        lock;
  647.  
  648.     if (wbs->sm_ArgList)
  649.     lock = CurrentDir(wbs->sm_ArgList->wa_Lock);
  650.     rc = main(0, (char **)wbs);
  651.     if (wbs->sm_ArgList)
  652.     CurrentDir(lock);
  653.     return rc;
  654. }
  655.